#include "myjni.h"
#include "platform_config.h"
#include <pthread.h>
#include <cutils/properties.h>
#include <cutils/sockets.h>
#include <poll.h>
#include <ctype.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <strings.h>
extern pthread_mutex_t mutex_Gprs;
//从EEPROM提取终端ID,SIM卡号码，服务器IP地址及端口号，车牌号码
u8 g_csqValue =0;
u8 g_weekCsqCounter=0;
unsigned int AlreadyInNet=0,GPRSLinKError=0;
extern u8 oilvalstatus, sendtimes;
static u32 current4minad;
char format[20];
extern u8 GPRS_RECEIVE[100];
u8 g_flagOfNewSMS=0;
extern unsigned char GPRSLink_Flag;
extern SysInf *p_sys;
extern float   oilchangeval;
static int32_t GPRSSecondCounter = 0;
extern int fd_gprs;
unsigned char CheckModeOk=0;
uint32_t SMSorCall=0;                 //0---无 1_CALL 2_SMS
static u8 code_jianquan[11];
static u8 jianquan_len;
extern _GPSDATAREG   gpsdata;
uint16_t MinuteTemp;       //分钟计数器
extern SysInf  SysInfor;
extern char iccid[PROPERTY_VALUE_MAX];
int send_data_error_count = 0;

void HEX_Print(char *buf, int len) {
    int ret = 0, i;
    char p[512] = {0};

    if (len > 255)
        return;
    for (i = 0; i < len; i++) {
        ret += sprintf(&p[ret], "%02x", buf[i]);
    }
    LOGE("%s", p);

}
//void Usart1_Printf(char *p, int len) {
//    LOGE("%s", p);
//}
void CHAR_Print(char *buf, int len) {
    int ret = 0, i;
    char printBuf[512] = {0};

    for (i = 0; i < len; i++) {
        ret += sprintf(printBuf + ret, "%c", buf[i]);
    }    
    LOGE("%s", printBuf);

}

void reinitSysPara() {
    LOGE("%s 重新初始化存储器参数", __func__);
    write_log_to_sdcard(LOG_TXT_PATH, "重新初始化存储器参数");
    SysInfor.magic = 0xdeadbeef;
	SysInfor.app_version = app_version;
    memset(SysInfor.IP,'\0',30);
    sprintf((char*)SysInfor.IP,"222.143.158.92");
    SysInfor.port = 8282;
    memset(SysInfor.terminalID, '\0', sizeof(SysInfor.terminalID));
    sprintf((char*)SysInfor.terminalID, "8816002");


    memset(&SysInfor.LocalPhoneNum1,'\0',13);
    sprintf((char*)&SysInfor.LocalPhoneNum1,"018618816002");

    memset(SysInfor.CarNumber, 0, sizeof(SysInfor.CarNumber));
    memset(SysInfor.CarNumber_utf8, 0, sizeof(SysInfor.CarNumber_utf8));
    sprintf((char*)&SysInfor.CarNumber+ 2,"K12345");
    SysInfor.CarNumber[0] = 0x8c;
    SysInfor.CarNumber[1] = 0x6b;
    sprintf((char*)&SysInfor.CarNumber_utf8,"豫K12345");


    SysInfor.depth = 250;
    SysInfor.ref_depth = 1030;
    SysInfor.machine_width = 300;
    SysInfor.angle = 0;
    SysInfor.a_sensor_height = 1500;
	SysInfor.sensor_model = 1;
	SysInfor.plough_model = 1;
	SysInfor.angle_b = 0;
	SysInfor.a_sensor_height_b = 1500;
	sprintf((char*)&SysInfor.plough_care_id, "0000000001");
    BlockWrite((char *)&SysInfor,SysInfLength, SYSINFO_SET);
}

void Init_Terminal(void)
{
    int ret;
    char md5[33];
    int at24c16_used = 0;

	flag_login = 0;
    memset((char *)&SysInfor, 0, sizeof(SysInfor));
    //checkExFile(); //first  check on system boot
    BlockRead((char *)&SysInfor, SysInfLength, SYSINFO_SET);
	Compute_buf_md5((char*)& SysInfor, md5, SysInfLength - sizeof(md5));
	if (SysInfor.magic != 0xdeadbeef || memcmp(SysInfor.md5, md5, sizeof(md5))) {
        ret = at24c16_read(I2C1, 0, SysInfLength, (unsigned char *)&SysInfor);
        if (ret > 0) {
            Compute_buf_md5((char *)&SysInfor, md5, SysInfLength - sizeof(md5));
            if(memcmp(SysInfor.md5, md5, sizeof(md5)) == 0) {
                LOGE("at24c16 i2c1 data ok");
                at24c16_used = 1;
            }
        } 
        if (at24c16_used == 0) {
            ret = at24c16_read(I2C3, 0, SysInfLength, (unsigned char *)&SysInfor);
            if (ret > 0) {
                Compute_buf_md5((char *)&SysInfor, md5, SysInfLength - sizeof(md5));
                if(memcmp(SysInfor.md5, md5, sizeof(md5)) == 0) {
                    LOGE("at24c16 i2c3 data ok");
                    at24c16_used = 1;
                }
            }
        }
        if (at24c16_used == 0) {
            LOGE("所有数据错误，工厂第一次烧录,初始化参数");
            write_log_to_sdcard(LOG_TXT_PATH, "所有数据错误，工厂第一次烧录,初始化参数");
            reinitSysPara();
        } else {
            BlockWrite((char *)&SysInfor,SysInfLength, SYSINFO_SET);
        }
    }
    property_set("rw.terminalID", SysInfor.terminalID);//app设置wifi热点名字用

}

void system_offline() {

    flag_login = 0; 
    send_data_error_count = 0; 
    write_log_to_sdcard(LOG_TXT_PATH, "连续发送4次失败 系统离线");
}



void UART1printfSysInfo( void )
{
    char Pinf[]="      *******  Star  ********       ";
    char Sayinfo1[]="Calculate area Version :2016-01-27-V1.00 use 485";
    char PNchar[]="The terminalID is : "  ;
    char PNchar1[]="The PhoneNum is : "  ;
    char IPInfochar[]="The System IPAdress is :"  ;
    char TheCarNumber[]="The CarNumber is : ";
    char Pind[]="      *******  END  *******     " ;

    Usart1_Printf((unsigned char *)Pinf,strlen(Pinf));
    Usart1_Printf((unsigned char *)Sayinfo1,strlen(Sayinfo1));

    Usart1_Printf((unsigned char *)PNchar,strlen(PNchar));
    Usart1_Printf((unsigned char *)SysInfor.terminalID, strlen(SysInfor.terminalID));

    Usart1_Printf((unsigned char *)PNchar1,strlen(PNchar1));
    Usart1_Printf((unsigned char *)SysInfor.LocalPhoneNum1,strlen(SysInfor.LocalPhoneNum1));


    Usart1_Printf((unsigned char *)IPInfochar,(strlen(IPInfochar)));
    Usart1_Printf((unsigned char *)SysInfor.IP,strlen(SysInfor.IP));



    LOGE("%s%s", TheCarNumber, SysInfor.CarNumber_utf8);


    Usart1_Printf((unsigned char *)Pind,strlen(Pind));

}

void pwr_start() {
    SIM300_PWRON();
   // Delay(10);
}

void device_init(void)
{
    Init_Terminal();
    UART1printfSysInfo();

}

void SaveAuthenticationCode(void)
{

    BlockWrite((char *)&SysInfor,SysInfLength, SYSINFO_SET);
}


void GetAuthenticationCode(void) {
    u8 i;
    u8 numberOf0xff = 0;
    for (i = 0; i < 10; i++) {
        if (SysInfor.code_jianquan[i] == 0) {
            numberOf0xff++;//超过7个，判定为无鉴权码
        }
    }

    if (numberOf0xff > 7)//无鉴权码时，清零鉴权CODE,
    {
        memset(SysInfor.code_jianquan, 0, 11);
        jianquan_len = 0;
        SaveAuthenticationCode();
        LOGE("鉴权码为空");
    } else {
        jianquan_len = strlen(SysInfor.code_jianquan);
        if (jianquan_len > 10) {
            jianquan_len = 10;
        }
        LOGE("本地鉴权码");
    }
}

int socket_cli = -1, socket_err_count = 0;
int socket_init(void) {
    struct sockaddr_in server_addr;
    struct timeval timeo = {3, 0};

    if (socket_cli > 0) {
        shutdown(socket_cli, SHUT_RDWR);
        close(socket_cli);
        socket_cli = -1;
    }
    socket_cli = socket(AF_INET, SOCK_STREAM, 0);
    if (socket_cli <= 0) {
        LOGE("create socket fail[%s]", strerror(errno));
        return -1;
    }
    //设置服务器地址
    bzero(&server_addr, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    server_addr.sin_port = htons(SysInfor.port);
    inet_pton(AF_INET, SysInfor.IP, &server_addr.sin_addr);
    LOGE("%s:ip=%s port=%d", __func__, SysInfor.IP, SysInfor.port);
    setsockopt(socket_cli, SOL_SOCKET, SO_SNDTIMEO, &timeo, (socklen_t)sizeof(timeo));
    int reuse = 1;
    setsockopt(socket_cli, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
    if (connect(socket_cli, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
        LOGE("%s connect fail[%d][%s]", __func__, errno, strerror(errno));
        goto out;
    }
    int block_flag = fcntl(socket_cli, F_GETFL);
    if(block_flag < 0) {
        LOGE("get socket fd flag error:%s\n", strerror(errno));
        goto out;
    } else {
        if(fcntl(socket_cli, F_SETFL, block_flag | O_NONBLOCK) < 0){
            LOGE("set socket fd non block error:%s\n", strerror(errno));
            goto out;
        }
    }
    return 0;
out:
    shutdown(socket_cli, SHUT_RDWR);
    close(socket_cli);
    socket_cli = -1;
    return -errno;
}

char socket_recv_buf[2048];

uint32_t GPRSDataSend(char *SendData, int len, long timeout_usec, int read_len)//与服务器通信 7e 转7d 02
{
    int i;
    u8 *pstr;
    int j =0 ;
    u8 *p;
    struct timeval tv;

    if (socket_cli == -1 && socket_init() != 0) {
        LOGE("socket初始化失败");
        return -1;
    }
    p =  malloc(len*2);
    pstr =  p;
    *pstr  = SendData[0];
    pstr++;
    for(i=1;i<len-1;i++)
    {
        if(SendData[i] == 0x7e)
        {
            *pstr = 0x7d;
            pstr ++;
            *pstr = 0x02;
            j++;
        }
        else if(SendData[i] == 0x7d)
        {
            *pstr = 0x7d;
            pstr ++;
            *pstr = 0x01;
            j++;
        }
        else
            *pstr = SendData[i];
        pstr ++;

    }
    *pstr = SendData[len-1];
    //LOGE("socket send[%d]:", len + j);
    HEX_Print((char *)p, len+j);
    int ret = 0;
    int total_len = len + j;
    int send_len = send(socket_cli, p, total_len, 0);
    if (send_len != total_len) {
        LOGE("%s send fail, send_len=%d, err[%d][%s]", __func__, send_len, errno, strerror(errno));//104:Connection reset by peer, 32:Broken pipe
        goto out;
    }
    if (timeout_usec <= 0) {
        free(p);
        return 0;
    }
    ret = recv(socket_cli, socket_recv_buf, sizeof(socket_recv_buf), 0);
    if (ret > 0) {
        socket_err_count = 0;
        socket_recv_buf[ret] = 0;
        check_server_parameter(socket_recv_buf);
        memcpy(SendData, socket_recv_buf, MIN(ret, read_len));
        LOGE("socket recv[%d]:", ret);
        HEX_Print(SendData, ret);
        free(p);
        return ret;
    } else {
        fd_set readfds;
        FD_ZERO(&readfds);
        FD_SET(socket_cli, &readfds);
        tv.tv_sec = MAX(1, timeout_usec/1000000/(socket_err_count+1));
        tv.tv_usec = timeout_usec%1000000;
        ret = select(socket_cli + 1, &readfds, NULL, NULL, &tv); //阻塞,err:0 timeout err:-1 错误见errno
        if (ret > 0 && FD_ISSET(socket_cli, &readfds)) {
            ret = read(socket_cli, socket_recv_buf, sizeof(socket_recv_buf));
            if (ret > 0) {
                socket_recv_buf[ret] = 0;
                check_server_parameter(socket_recv_buf);
                memcpy(SendData, socket_recv_buf, MIN(ret, read_len));
                socket_err_count = 0;
                LOGE("socket recv[%d]:", ret);
                HEX_Print(SendData, ret);
                free(p);
                return ret;
            }
        } else if (ret == 0) {//timeout
            LOGE("ret=%d, select timeout err=%s", ret, strerror(errno));
        } else if (ret < 0 && errno != EINTR) {
            LOGE("ret=%d, select timeout err=%s", ret, strerror(errno));
        }
    }
out:
    free(p);
    if (errno == ECONNRESET || errno == EPIPE || (socket_err_count++ > 3)) {
        socket_err_count = 0;
        socket_init();
    }
    return -1;
}


extern int ultra_depth;
void check_server_parameter(const char *p) {
    char *start;
    char buf[64];
    int i;
    char c;
    int set_flags = 0;

	/*if (strlen(p) < 14)
		return;*/
    p += 14;
    LOGE("command = %s", p);
    start = strstr(p, "setup car:");
    if (start) {
        start += 10;
        bzero(buf, sizeof(buf));
        memcpy(buf, start, 8);
        LOGE("服务器参数设置 车牌号:%s", buf);
        set_flags = 1;
    }

    start = strstr(p, "setup id:");
    if (start) {
        start += 9;
        bzero(buf, sizeof(buf));
        memcpy(SysInfor.terminalID, start, 7);
        sprintf(SysInfor.LocalPhoneNum1, "01861%s", SysInfor.terminalID);
        LOGE("服务器参数设置 ID号:%s", SysInfor.terminalID);
        set_flags = 2;
    }

    start = strstr(p, "setup ip:");
    if (start) {
        start += 9;
        bzero(buf, sizeof(buf));
        i = 0;
        c = start[0];
        while (c && (isdigit(c) || c == '.'))
            c = start[++i];
        bzero(SysInfor.IP, sizeof(SysInfor.IP));
        memcpy(SysInfor.IP, start, i);
        start += i;
        i = 0;
        if (start[0] == ',') {
            c = *(++start);
            while(c && isdigit(c))
                c = start[++i];
            memcpy(buf, start, i);
            SysInfor.port = atoi(buf);
        }
        LOGE("服务器参数设置 IP:%s 端口:%hd", SysInfor.IP, SysInfor.port);
        set_flags = 2;
    }

    start = strstr(p, "setup width:");
    if (start) {
        start += 12;
        bzero(buf, sizeof(buf));
        i = 0;
        c = start[0];
        while (c && isdigit(c))
            c = start[++i];
        memcpy(buf, start, i);
        LOGE("服务器参数设置 宽度:%d", atoi(buf));
        SysInfor.machine_width = atoi(buf); 
        set_flags = 1;
    }

    start = strstr(p, "setup depth ratio:");
    if (start) {
        start += 18;
        bzero(buf, sizeof(buf));
        i = 0;
        c = start[0];
        while (c && (isdigit(c) || c == '.'|| c == '-'))
            c = start[++i];
        memcpy(buf, start, i);
        LOGE("服务器参数设置 深度比例:%f", atof(buf));
        SysInfor.a_sensor_height = atof(buf); 
        set_flags = 1;
    }
    
    start = strstr(p, "setup angle:");
    if (start) {
        start += 12;
        bzero(buf, sizeof(buf));
        i = 0;
        c = start[0];
		while (c && (isdigit(c) || c == '-'))
            c = start[++i];
        memcpy(buf, start, i);
        SysInfor.angle = atoi(buf); 
        LOGE("服务器参数设置 零点角度:%d", atoi(buf));
        set_flags = 1;

    }

    start = strstr(p, "take a picture");
    if (start) {
        server_request_cmd |= SERVER_TAKE_PICTURE;
        LOGE("服务器参数设置 拍照");
    }

    start = strstr(p, "read device");
    if (start) {
        server_request_cmd |= SERVER_READ_DEVICE;
        LOGE("服务器参数设置 读取设备信息");
    }

	start = strstr(p, "auto correction");
	if (start) {
		int angle = (int)(g_currentAngle * 100);
		SysInfor.angle = angle;

		LOGE("服务器参数设置 自动矫正零点角度:%d", (int)(g_currentAngle * 100));
	}

	start = strstr(p, "depth adjust:");
	if (start) {
		start += 13;
		bzero(buf, sizeof(buf));
		i = 0;
		c = start[0];
		while (c && (isdigit(c) || c == '.' || c == '-'))
			c = start[++i];
		memcpy(buf, start, i);
		double depth = atof(buf);
		double modulus = depth / (double)ultra_depth;
		double sensorHeight = (double)SysInfor.a_sensor_height * modulus;
		if (sensorHeight <2000 && sensorHeight > -2000)
		{
			SysInfor.a_sensor_height = sensorHeight;
		}

		LOGE("服务器参数设置 自动设置深度比例:%d", SysInfor.a_sensor_height);
		set_flags = 1;
	}

	start = strstr(p, "setup b angle:");
	if (start) {
		start += 14;
		bzero(buf, sizeof(buf));
		i = 0;
		c = start[0];
		while (c && (isdigit(c) || c == '-'))
			c = start[++i];
		memcpy(buf, start, i);
		SysInfor.angle_b = atoi(buf);
		LOGE("服务器参数设置 零点角度B:%d", atoi(buf));
		set_flags = 1;
	}

	start = strstr(p, "auto b correction");
	if (start) {
		int angle = (int)(g_currentAngle_b * 100);
		SysInfor.angle_b = angle;

		LOGE("服务器参数设置 自动矫正零点角度B:%d", (int)(g_currentAngle_b * 100));
	}

	start = strstr(p, "depth b adjust:");
	if (start) {
		start += 15;
		bzero(buf, sizeof(buf));
		i = 0;
		c = start[0];
		while (c && (isdigit(c) || c == '.' || c == '-'))
			c = start[++i];
		memcpy(buf, start, i);
		double depth = atof(buf);
		double modulus = depth / (double)ultra_depth;
		double sensorHeight = (double)SysInfor.a_sensor_height_b * modulus;
		if (sensorHeight <2000 && sensorHeight > -2000)
		{
			SysInfor.a_sensor_height_b = sensorHeight;
		}

		LOGE("服务器参数设置 自动设置深度比例B:%d", SysInfor.a_sensor_height);
		set_flags = 1;
	}

	start = strstr(p, "set sensor model:");
	if (start) {
		start += 17;
		bzero(buf, sizeof(buf));
		i = 0;
		c = start[0];
		while (c && isdigit(c))
			c = start[++i];
		memcpy(buf, start, i);
		if (atoi(buf) == 1 || atoi(buf) == 2 || atoi(buf) == 3)
		{
			SysInfor.sensor_model = atoi(buf);
			LOGE("服务器参数设置 传感器模式:%d", atoi(buf));
		}

		set_flags = 1;
	}

	start = strstr(p, "set plough model:");
	if (start) {
		start += 17;
		bzero(buf, sizeof(buf));
		i = 0;
		c = start[0];
		while (c && isdigit(c))
			c = start[++i];
		memcpy(buf, start, i);
		if (atoi(buf) == 0 || atoi(buf) == 1)
		{
			SysInfor.plough_model = atoi(buf);
			LOGE("服务器参数设置 犁具识别器模式:%d", atoi(buf));
		}

		set_flags = 1;
	}

	start = strstr(p, "set plough id:");
	if (start) {
		start += 14;
		bzero(buf, sizeof(buf));
		i = 0;
		c = start[0];
		while (c && isdigit(c))
			c = start[++i];
		memcpy(buf, start, i);
		strcpy(SysInfor.plough_care_id, buf);
		LOGE("服务器参数设置 犁具识别器ID:%s", SysInfor.plough_care_id);

		set_flags = 1;
	}

	start = strstr(p, "setup depth ratio b:");
	if (start) {
		start += 20;
		bzero(buf, sizeof(buf));
		i = 0;
		c = start[0];
		while (c && (isdigit(c) || c == '.' || c == '-'))
			c = start[++i];
		memcpy(buf, start, i);
		LOGE("服务器参数设置 深度比例:%f", atof(buf));
		SysInfor.a_sensor_height_b = atof(buf);
		set_flags = 1;
	}

	start = strstr(p, "reboot");
	if (start) {
		set_flags = 2;
	}

    if (set_flags) {
        disp_set_para = 1;
        BlockWrite((char *)&SysInfor,SysInfLength, SYSINFO_SET);

		if (set_flags == 2)
		{
			sleepMsec(10000);
			system("reboot");
		}
    }
}


u8 register_server()//0x0100注册
{
    u8 i;
    u32 num_temp;
    char format[13];
    u8 *pstr;
    u8 *pstr2;
    u8 *p;
    
    p  = (u8 *)malloc(100); //终端注册
    pstr = p;

    *pstr = 0x7e;
    pstr++ ;
    *pstr = 0x01;
    pstr++ ;
    *pstr = 0x00;//注册ID

    pstr++ ;
    *pstr = 0x00;
    pstr++ ;
    //*pstr =0x2d;
    *pstr = 37 + strlen(SysInfor.CarNumber);
    pstr2 = (u8*)SysInfor.LocalPhoneNum1;
    LOGE("register Phone Number:%s,Car Number:%s,Terminal ID:%s", pstr2, SysInfor.CarNumber_utf8, SysInfor.terminalID);

    for(i=0;i<6;i++)
    {
        strncpy(format,(char*)pstr2,2);
        format[2] = 0;
        num_temp = atoi(format);
        pstr2 +=2;
        pstr++ ;
        *pstr =( (num_temp/10)*16+num_temp%10);
    }
    pstr++ ;
    *pstr =RecodeCnter %0xffff/0xff;
    pstr++ ;
    *pstr = RecodeCnter %0xff;


    pstr++ ;
    *pstr = 0x0;
    pstr ++;
    *pstr = 0x0;//省城ID
    pstr ++;
    *pstr = 0x0;
    pstr ++;
    *pstr = 0x0;//市城ID
    pstr ++;
    strncpy((char*)pstr,"LMDZ",5);
    pstr += 5;
    strncpy((char*)pstr,"2015.8.14 use 485\r\n",20);
    pstr += 20;
    strncpy((char*)pstr,(char *)SysInfor.terminalID,7);//终端ID
    pstr += 7;
    *pstr = 2;
    pstr ++;
    strncpy((char*)pstr,SysInfor.CarNumber,strlen(SysInfor.CarNumber));
    pstr += strlen(SysInfor.CarNumber);

    *pstr = p[1];
    pstr2 = p;
    pstr2 += 2;

    for(i=0;i<56;i++)
    {
        *pstr ^= *pstr2;
        pstr2++;

    }
    pstr++;
    *pstr = 0x7e;
    int len = GPRSDataSend((char *)p, 52 + strlen(SysInfor.CarNumber), MAX_SELECT_TIME, 99);
    if (len > 0) {
        if((p[0] == 0x7e) && (p[1] == 0x81) && (p[15] == 0 ))//终端注册应答
        {
            LOGE("$GSM reg ok!");
             send_data_error_count = 0;
            jianquan_len = MIN((p[4]-3), 10);
            pstr = (u8*)p;
            pstr += 16;
            for(i=0;i<jianquan_len;i++)
            {
                SysInfor.code_jianquan[i] = *pstr ;
                pstr ++;
            }
            SaveAuthenticationCode();
            free(p);
            return 1;
        }
    }
    if (++send_data_error_count > 4) { 
        system_offline();
    }   
    LOGE("服务器无响应[%d]:", len);
    free(p);

    return 0;

}

u8 authentication()//0x0x0102鉴权
{
    char format[13];
    u8 i;
    u32 temp_num;
    u8 *p;
    u8 *pstr;
    u8 *pstr2;
    p = malloc(100);
    pstr = p;
    *pstr = 0x7e;
    pstr++ ;
    *pstr = 0x01;
    pstr++ ;
    *pstr = 0x02;

    pstr++ ;
    *pstr = 0x00;
    pstr++ ;
    *pstr = jianquan_len;

    pstr2 = (u8 *)SysInfor.LocalPhoneNum1;
    for(i=0;i<6;i++)
    {
        strncpy(format,(char*)pstr2,2);
        format[2] = 0;
        temp_num = atoi(format);
        pstr2 +=2;
        pstr++ ;
        *pstr =( (temp_num/10)*16+temp_num%10);
    }
    pstr++ ;
    *pstr =RecodeCnter %0xffff/0xff;
    pstr++ ;
    *pstr = RecodeCnter %0xff;
    pstr ++;
    for(i=0;i<jianquan_len;i++)
    {
        *pstr = SysInfor.code_jianquan[i] ;
        pstr ++;
    }

    *pstr = p[1];
    pstr2 = p;
    pstr2 +=2;
    for(i=0;i<(11+jianquan_len);i++)
    {
        *pstr ^= *pstr2;
        pstr2++;

    }
    pstr++;
    *pstr = 0x7e;
    LOGE("$Send authentication:");

    int len = GPRSDataSend((char *)p, (15+jianquan_len), MAX_SELECT_TIME, 99);
    if((len > 0) && (p[0] ==0x7e) && (p[1] == 0x80)) {//终端注册应答
        free(p);
         send_data_error_count = 0;
        return 1;
    }
    if (++send_data_error_count > 4) { 
        system_offline();
    }   
    LOGE("服务器无响应[%d]:", len);
    free(p);
    return 0;
}

u8 upload_verson()//0x0f15 版本信息上报
{
    u8 i;
    u32 temp_num;
    char format[13];
    u8 *pstr;
    u8 *pstr2;
    u8 *p;

    p = malloc(100);
    pstr = p; //终端注册

    *pstr = 0x7e;
    pstr++ ;
    *pstr = 0x0f;
    pstr++ ;
    *pstr = 0x15;//上传 版本信息
    pstr++ ;
    *pstr = 0x00;
    pstr++ ;
    *pstr = 0x36;

    pstr2 = (u8 *)SysInfor.LocalPhoneNum1;
    for(i=0;i<6;i++)
    {
        strncpy(format,(char*)pstr2,2);
        format[2] = 0;
        temp_num = atoi(format);
        pstr2 +=2;
        pstr++ ;
        *pstr =( (temp_num/10)*16+temp_num%10);
    }
    pstr++ ;
    *pstr =RecodeCnter %0xffff/0xff;
    pstr++ ;
    *pstr = RecodeCnter %0xff;

    pstr++ ;
    *pstr = 0x03;

    pstr++ ;
    *pstr = 0x1;
    pstr++ ;
    *pstr = strlen("SIM900A-v1.02013/5/30");
    pstr++ ;
    strncpy((char*)pstr,"SIM900A-v1.02013/5/30",strlen("SIM900A-v1.02013/5/30"));

    pstr+= strlen("SIM900A-v1.02013/5/30"); ;
    *pstr = 0x2;
    pstr++ ;
    *pstr = strlen("v1.0.0");
    pstr++ ;
    strncpy((char*)pstr,"v1.0.0",strlen("v1.0.0"));
    pstr +=strlen("v1.0.0"); ;
    *pstr = 0x3;
    pstr++ ;
//  *pstr = 7;
//  pstr++ ;
//  strncpy((char*)pstr,(char *)SysInfor.LocalPhoneNum,7);

//  pstr+= 7;
    *pstr = 20;
    pstr++ ;
    //char ccidCode[PROPERTY_VALUE_MAX];
    //memset(ccidCode, 0, sizeof(ccidCode));
    property_get("gsm.iccid", iccid, "");
    LOGE("iccid=%s", iccid);
    strncpy((char*)pstr, iccid, 20);

    pstr+= 20;
    *pstr = p[1];
    pstr2 = p;
    pstr2 += 2;
    for(i=0;i<65;i++)
    {
        *pstr ^= *pstr2;
        pstr2++;

    }
    pstr++;
    *pstr = 0x7e;
    LOGE("$Send Version:");
    //Usart1_Printf("\r\n",strlen("\r\n"));
    
    int len = GPRSDataSend((char *)p, 69, MAX_SELECT_TIME, 99); 
    if (len > 0 && p[0] == 0x7e && p[1] == 0x80) {
         send_data_error_count = 0;
        free(p);
        return 1;
    }
    if (++send_data_error_count > 4) { 
        system_offline();
    }   
    LOGE("服务器无响应[%d]:", len);
    free(p);
    
    return 0;
}


u8 stateOfLogin=0;
u8 errorCounterOfAuthentication=0;//鉴权失败次数
u8 g_reg_counter=0;

//注册鉴权
void LoginAndAuthentication(void)
{
    if(jianquan_len ==0 && (SysInfor.code_jianquan[0] + SysInfor.code_jianquan[1]) ==0)
    {
        LOGE("获取鉴权码");
        stateOfLogin = register_server();//注册
    }
    else
    {
        stateOfLogin =1;
    }
    if (stateOfLogin == 0)
    {
        if(++g_reg_counter>10)
        {
            g_reg_counter=0;
            Usart1_Printf("$reg error!\r\n",strlen("\r\n$reg succed!\r\n"));
         //   SysRestart();//重启 sclu TODO
        }
    }
    else
    {
        usleep (1*1000*100);
        if(1 == authentication())//鉴权
        {
            flag_login = 1;
            write_log_to_sdcard(LOG_TXT_PATH, "鉴权成功,系统上线");
            LOGE("鉴权成功,系统上线");
            if(1 == upload_verson())//上传版本信息
            {
                Usart1_Printf("$upload_verson succed!",strlen("\r\n$upload_verson succed!\r\n"));

            }
            if (1==plus())//心跳
            {
                LOGE("%s $plus succed",__func__);
            }
        }
        else
        {
            LOGE("鉴权失败");
            if(++errorCounterOfAuthentication >=3)//超过3次，清空鉴权码
            {
                errorCounterOfAuthentication =0;
                jianquan_len =0;
                memset(SysInfor.code_jianquan, 0, sizeof(SysInfor.code_jianquan) );
                SaveAuthenticationCode();
                stateOfLogin =0;
            }
        }


    }
}


u8 plus()//0x0002心跳
{
    char format[13];
    u8 i;
    u32 temp_num;
    u8 *p;

    u8 *pstr;
    u8 *pstr2;
    p = malloc(100);
    pstr = p;
    *pstr = 0x7e;
    pstr++ ;
    *pstr = 0x00;
    pstr++ ;
    *pstr = 0x02;

    pstr++ ;
    *pstr = 0x00;
    pstr++ ;
    *pstr = 0x00;

    pstr2 = (u8 *)SysInfor.LocalPhoneNum1;
    for(i=0;i<6;i++)
    {
        strncpy(format,(char*)pstr2,2);
        format[2] = 0;
        temp_num = atoi(format);
        pstr2 +=2;
        pstr++ ;
        *pstr =( (temp_num/10)*16+temp_num%10);
    }
    pstr++ ;
    *pstr =RecodeCnter %0xffff/0xff;
    pstr++ ;
    *pstr = RecodeCnter %0xff;
    pstr ++;

    *pstr = p[1];
    pstr2 = p;
    pstr2 +=2;
    for(i=0;i<11;i++)
    {
        *pstr ^= *pstr2;
        pstr2++;

    }
    pstr++;
    *pstr = 0x7e;
    LOGE("$Send plus:");
    //HEX_Print((char *)p,15);

    int len = GPRSDataSend((char *)p, 15, MAX_SELECT_TIME, 99);
    if (len > 0 && p[0] == 0x7e && p[1] == 0x80) {
         send_data_error_count = 0;
        free(p);
        return 1;
    }
    if (++send_data_error_count > 4) { 
        system_offline();
    }   
    LOGE("服务器无响应, len=%d", len);
    free(p);
    return 0;
}




void UTC2China(u8* pdata)
{
    u8 ChinaYear,ChinaMonth,ChinaDay,ChinaSeconds,ChinaMinutes,ChinaHour;

    ChinaYear = *pdata ;
    ChinaMonth = *(pdata+1);
    ChinaDay = *(pdata+2);
    ChinaSeconds = *(pdata+5);
    ChinaMinutes = *(pdata+4);
    ChinaHour = (*(pdata+3)+8);
    if (ChinaHour>23)
    {
        ChinaHour-=24;
        ChinaDay++;
        switch (ChinaMonth)
        {
            case 1:
                if (ChinaDay>31)
                {
                    ChinaDay=1;
                    ChinaMonth++;
                }
                break;
            case 2:
                if ((0==ChinaYear%4 && 0!=ChinaYear%100) || 0==ChinaYear%400)
                {
                    if (ChinaDay>29)
                    {
                        ChinaDay=1;
                        ChinaMonth++;
                    }
                }
                else
                {
                    if (ChinaDay>28)
                    {
                        ChinaDay=1;
                        ChinaMonth++;
                    }
                }
                break;
            case 3:
                if (ChinaDay>31)
                {
                    ChinaDay=1;
                    ChinaMonth++;
                }
                break;
            case 4:
                if (ChinaDay>30)
                {
                    ChinaDay=1;
                    ChinaMonth++;
                }
                break;
            case 5:
                if (ChinaDay>31)
                {
                    ChinaDay=1;
                    ChinaMonth++;
                }
                break;
            case 6:
                if (ChinaDay>30)
                {
                    ChinaDay=1;
                    ChinaMonth++;
                }
                break;
            case 7:
                if (ChinaDay>31)
                {
                    ChinaDay=1;
                    ChinaMonth++;
                }
                break;
            case 8:
                if (ChinaDay>31)
                {
                    ChinaDay=1;
                    ChinaMonth++;
                }
                break;
            case 9:
                if (ChinaDay>30)
                {
                    ChinaDay=1;
                    ChinaMonth++;
                }
                break;
            case 10:
                if (ChinaDay>31)
                {
                    ChinaDay=1;
                    ChinaMonth++;
                }
                break;
            case 11:
                if (ChinaDay>30)
                {
                    ChinaDay=1;
                    ChinaMonth++;
                }
                break;
            case 12:
                if (ChinaDay>31)
                {
                    ChinaDay=1;
                    ChinaMonth=1;
                    ChinaYear++;
                }
                break;
            default:break;
        }
    }
    *(pdata)    = ( (ChinaYear/10)*16+ChinaYear%10)  ;
    *(pdata+1) = ( (ChinaMonth/10)*16+ChinaMonth%10)   ;
    *(pdata+2) = ( (ChinaDay/10)*16+ChinaDay%10)   ;
    *(pdata+5)  = ( (ChinaSeconds/10)*16+ChinaSeconds%10)   ;
    *(pdata+4) = ( (ChinaMinutes/10)*16+ChinaMinutes%10)  ;
    *(pdata+3) = ( (ChinaHour/10)*16+ChinaHour%10)   ;

}


static void getTime(char *buf) {
    time_t timep;
    time(&timep);

    struct tm * ptm;
    long ts; 
    char str[20];    

    ts = time(NULL);
    ptm = localtime(&ts);

    int y, month, d, h, m, s, week;
    y = ptm->tm_year + 1900 - 2000;
    month = ptm->tm_mon+1;
    d = ptm->tm_mday;
    h = ptm->tm_hour-8;
    m = ptm->tm_min;
    s = ptm->tm_sec;
    //struct tm * tm = gmtime(&timep);
    //week = tm->tm_wday;

    buf[0] = (char)y;
    buf[1] = (char)month;
    buf[2] = (char)d;
    buf[3] = (char)h;
    buf[4] = (char)m;
    buf[5] = (char)s;
    //LOGE("current y=%d, month=%d, d = %d, h:%d, m:%d, s:%d\n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); 
}

void calAreaAndWight(char *p, unsigned int area, unsigned short areaRate, unsigned short depth_temp, unsigned short depthRate_temp, unsigned int work_length, unsigned short work_time)
{
    u8 i;
    u8 * p_time;
    char * pstr;
    char *pstr2;
    u32 wei;
    u32 jing;
    u32 temp_num;
    u8 * Pdata;
    //u32 area_temp = g_areaOfFarmland*1000;


    pstr = p;
    memset(pstr, 0, 57);


    *pstr = 0x7e;
    pstr++ ;
    *pstr = 0x09;
    pstr++ ;
    *pstr = 0x00;//上传

    pstr++ ;
    *pstr = 0x00;
    pstr++ ;
    *pstr =42;

    pstr2 = (char *)SysInfor.LocalPhoneNum1;

    for(i=0;i<6;i++)
    {
        strncpy(format,pstr2,2);
        format[2] = 0;
        temp_num = atoi(format);
        pstr2 +=2;
        pstr++ ;
        *pstr =((temp_num/10)*16+temp_num%10);
    }
    pstr++ ;
	*pstr = (u16)RecodeCnter >> 8;
    pstr++ ;
    *pstr = RecodeCnter;
    Pdata  = (u8*)pstr;
    Pdata += 1;
    *Pdata = 0xf2;	//消息类型0xf1为收割机,0xf2为深耕机
    Pdata += 1;
    *Pdata = 0x02;	//协议版本号
	//gps信息
	wei = (u32)(cur_lat * 1000000);//维度
	Pdata++;
	*Pdata = (wei >> 24);
	Pdata++;
	*Pdata = (wei >> 16);
	Pdata++;
	*Pdata = (wei >> 8);
	Pdata++;
	*Pdata = wei;

	jing = (u32)(cur_lon * 1000000);//经度
	Pdata++;
	*Pdata = (jing >> 24);
	Pdata++;
	*Pdata = (jing >> 16);
	Pdata++;
	*Pdata = (jing >> 8);
	Pdata++;
	*Pdata = jing;

	Pdata++;
	*Pdata = 0;//高度 1
	Pdata++;
	*Pdata = 0; //高度 1

	temp_num = (u16)(10 * gps_speed);
	Pdata++;
	*Pdata = temp_num >> 8;
	Pdata++;
	*Pdata = temp_num;//填充 速度

	temp_num = (u16)gps_bearing;
	Pdata++;
	*Pdata = temp_num >> 8;
	Pdata++;
	*Pdata = temp_num;//角度

	Pdata++;
	p_time = Pdata;
	*Pdata = gps_year % 100;//year
	Pdata++;
	*Pdata = gps_mon % 100;//month
	Pdata++;
	*Pdata = gps_day % 100;//date
	Pdata++;
	*Pdata = gps_hour % 100;//hour
	Pdata++;
	*Pdata = gps_min % 100;//minute
	Pdata++;
	*Pdata = gps_sec % 100; //second
	UTC2China(p_time);//整理时间格式	


    Pdata++;
    *Pdata = area>>24;//
    Pdata++;
    *Pdata = area>>16;//
    Pdata++;
    *Pdata = area>>8;//
    Pdata++;
    *Pdata = area;//面积，保留三个小数点，单位亩
    Pdata++;
    *Pdata = depth_temp>>8;//
    Pdata++;
    *Pdata = depth_temp;//
    Pdata++;
    *Pdata = depthRate_temp>>8;//
    Pdata++;
    *Pdata = depthRate_temp;//  产量，保留三个小数点，单位千克

    Pdata++;
    *Pdata = areaRate>>8;//    面积合格率高位
    Pdata++;
    *Pdata = areaRate;//   面积合格率低位
    Pdata++;    


    *Pdata = work_length>>24;
    Pdata++;
    *Pdata = work_length>>16;
    Pdata++;
    *Pdata = work_length>>8;
    Pdata++;
    *Pdata = work_length;
    Pdata++;
    *Pdata = work_time>>8;
    Pdata++;
    *Pdata = work_time;
    Pdata ++;
	*Pdata = SysInfor.plough_model; //是否安装犁具识别器,1表示安装，0表示未安装
	Pdata++;
	*Pdata = plough_state; //是否检测到犁具识别器,1表示读取到ID，0表示未读取到ID
	Pdata++;
    Pdata += 2;//unused

    *Pdata = p[1];
    pstr2 = p;
    pstr2 +=2;
    for(i=0;i<53;i++)
    {
        *Pdata ^= *pstr2;
        pstr2++;

    }
    Pdata++;
    *Pdata = 0x7e;
}

static char xor_gen(char *buf, int len) {
    int i;
    char result, *temp;

    result = buf[1];
    temp = buf;
    temp += 2;
    for (i = 0; i < len; i++) {
        result ^= *temp;
        temp++;
    }
    return result;
}

static char gen_xor(char *buf, int len) {
    char start = buf[0];
    int i;

    for (i = 1; i < len; i++)
        start ^= buf[i];

    return start;
}

u8 locat_to_list(int work_state, int depth)//0x0200 位置信息
{
    u8 i;
    u32 wei;
    u32 jing;
    u32 temp_num;
    u8 * Pdata;
    u8 * p_time;
    u8 *pstr;
    u8 *pstr2;
    u8 *p;

    p = malloc(46);
    pstr = p; //终端注册


    *pstr = 0x7e;
    pstr++ ;
    *pstr = 0x02;
    pstr++ ;
    *pstr = 0x00;//位置信息
    pstr++ ;
    *pstr = 0x00;
    pstr++ ;
    *pstr = 0x1F;

	pstr2 = (u8*)SysInfor.LocalPhoneNum1;
	//LOGE("Phone Number:%s,Car Number:%s,Terminal ID:%s", pstr2, SysInfor.CarNumber_utf8, SysInfor.terminalID);
	for (i = 0; i < 6; i++)
	{
		strncpy(format, (char*)pstr2, 2);
		format[2] = 0;
		temp_num = atoi(format);
		pstr2 += 2;
		pstr++;
		*pstr = ((temp_num / 10) * 16 + temp_num % 10);
	}
	pstr++;
	*pstr = (u16)RecodeCnter >> 8;
	pstr++;
	*pstr = RecodeCnter;
	pstr++;
	*pstr = 0x0;
	pstr++;
	*pstr = 0x0;
	pstr++;
	*pstr = 0x0;
	pstr++;
	*pstr = 0x0;//报警标志位

	pstr++;
	*pstr = 0x00;
	pstr++;
	*pstr = 0x04;
	pstr++;
	*pstr = 0x00;
	pstr++;
	*pstr = 0x03;// 状态

	Pdata = pstr;

	//gps信息
	wei = (u32)(cur_lat * 1000000);//维度
	Pdata++;
	*Pdata = (wei >> 24);
	Pdata++;
	*Pdata = (wei >> 16);
	Pdata++;
	*Pdata = (wei >> 8);;
	Pdata++;
	*Pdata = wei;

	jing = (u32)(cur_lon * 1000000);//经度
	Pdata++;
	*Pdata = (jing >> 24);
	Pdata++;
	*Pdata = (jing >> 16);
	Pdata++;
	*Pdata = (jing >> 8);
	Pdata++;
	*Pdata = jing;

	Pdata++;
	*Pdata = 0;//高度 1
	Pdata++;
	*Pdata = 0; //高度 1

	temp_num = (u16)(10 * gps_speed);
	Pdata++;
	*Pdata = temp_num >> 8;
	Pdata++;
	*Pdata = temp_num;//填充 速度

	temp_num = (u16)gps_bearing;
	Pdata++;
	*Pdata = temp_num >> 8;
	Pdata++;
	*Pdata = temp_num;//角度

	Pdata++;
	p_time = Pdata;
	*Pdata = gps_year % 100;//year
	Pdata++;
	*Pdata = gps_mon % 100;//month
	Pdata++;
	*Pdata = gps_day % 100;//date
	Pdata++;
	*Pdata = gps_hour % 100;//hour
	Pdata++;
	*Pdata = gps_min % 100;//minute
	Pdata++;
	*Pdata = gps_sec % 100; //second
	UTC2China(p_time);//整理时间格式



    Pdata++;
    //----30 01 XX---//
    *Pdata  = 0x30;
    Pdata++;
    *Pdata  = work_state;
    Pdata++;
    *Pdata  = depth;
    Pdata++;
    //----30 01 XX---//
    *Pdata = p[1];
    pstr2 = p;
    pstr2 +=2;
    for(i=0;i<42;i++)//39
    {
        *Pdata ^= *pstr2;
        pstr2++;

    }
    Pdata++;
    *Pdata = 0x7e;
    
	if (jing != 0 || wei != 0)
	{
		add_offline_data_list(&gps_data_head, p, 46);
		offline_gps_count++;
	}
    
    return 0;
}

void mushu_to_list(unsigned int area_temp, unsigned short areaRate_temp, unsigned short depth_temp, unsigned short depthRate_temp, u32 work_length, unsigned short work_time) {
    unsigned char *data = malloc(57);

    calAreaAndWight((char *)data, area_temp, areaRate_temp, depth_temp, depthRate_temp, work_length, work_time);
    add_offline_data_list(&mushu_data_head, data, 57);
    write_gps_info("保存亩数: %d %d %d %d %d %d", area_temp, areaRate_temp, depth_temp, depthRate_temp, work_length, work_time);
    HEX_Print((char *)data, 57);
}
